// 创建用户相关的小仓库
import { defineStore } from 'pinia'
// 引入请求相关的变量和返回值类型
import {
  loginFormData,
  loginResponseData,
  userInfoResponesData,
} from '@/api/user/type'
import type { UserState } from '@/store/modules/type/type'
// 引入接口
import { reqLogin, reqUserInfo, reqLogout } from '@/api/user/index'
// 引入封装之后的TOKEN本地存储操作
import { SET_TOKEN, GET_TOKEN, REMOVE_TOKEN } from '@/utils/token'

// 引入路由数据
import { constantRoute, asyncRoute, anyRoute } from '@/router/routes'

// 引入路由器 动态添加路由
import router from '@/router'
//引入深拷贝方法
//@ts-expect-error
import cloneDeep from 'lodash/cloneDeep'
// 根据用户所携带的信息 筛选对应权限的异步路由内容 然后和同步路由一起分配给仓库属性menuRoutes 动态创建菜单
function filterAsyncRoute(asyncRoute: any, routes: any) {
  return asyncRoute.filter((item: any) => {
    if (routes.includes(item.name)) {
      // 递归子路由
      if (item.children && item.children.length > 0) {
        filterAsyncRoute(item.children, routes)
      }
      return true
    }
  })
}
let arrRemoveRouteFunction = new Array()
// 创建用户信息相关的仓库
let userMessageStore = defineStore('User', {
  // 数据
  state: (): UserState => {
    return {
      token: GET_TOKEN() || '',
      // 动态创建左侧路由菜单
      menuRoutes: constantRoute,
      username: '',
      avatar: '',
      buttons: [],
    }
  },
  // 处理异步 | 逻辑的地方
  actions: {
    // 登录
    async userLogin(loginFrom: loginFormData) {
      // 发送axios请求
      let result: loginResponseData = await reqLogin(loginFrom)
      if (result.code == 200) {
        // 登录成功
        this.token = result.data as string
        // 本地持久化存储
        SET_TOKEN(result.data as string)
        // 保障当前async函数返回一个成功的Promise
        return 'ok'
      } else {
        // 登录失败 返回一个失败的Promise对象
        return Promise.reject(new Error(result.data || result.message))
      }
    },
    async userInfo() {
      let result: userInfoResponesData = await reqUserInfo()
      if (result.code == 200) {
        this.username = result.data.name
        this.avatar = result.data.avatar
        this.buttons = result.data.buttons
        // 计算当前用户需要展示的异步路由内容
        const userAsyncRoute = filterAsyncRoute(
          cloneDeep(asyncRoute),
          result.data.routes,
        )
        // 菜单需要的数据整理完毕
        this.menuRoutes = [...constantRoute, ...userAsyncRoute, ...anyRoute]
        // 目前路由器管理的只有常量路由:用户计算完毕异步路由、任意路由动态追加
        ;[...userAsyncRoute, ...anyRoute].forEach((route: any) => {
          // 向路由器添加异步路由 并将addRoute方法返回值（函数）进行保存
          arrRemoveRouteFunction.push(router.addRoute(route))
        })
        return 'ok'
      } else {
        return Promise.reject(new Error(result.message))
      }
    },

    // 退出登录
    async userLogout() {
      let result: any = await reqLogout()
      if (result.code == 200) {
        this.username = ''
        this.avatar = ''
        this.token = ''
        // 向路由器销毁异步路由
        for (let i = 0; i < arrRemoveRouteFunction.length; i++) {
          arrRemoveRouteFunction[i]() // 调用数组中的函数
        }
        // 清除TOKEN
        REMOVE_TOKEN()
        return 'ok'
      } else {
        return Promise.reject(new Error('退出失败'))
      }
    },
  },
  getters: {},
})

// 对外暴露
export default userMessageStore
